package com.system.connect.springboot_flowers.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.system.connect.springboot_flowers.dto.OrderCreateDTO;
import com.system.connect.springboot_flowers.entity.Order;
import com.system.connect.springboot_flowers.entity.OrderItem;
import com.system.connect.springboot_flowers.mapper.OrderItemMapper;
import com.system.connect.springboot_flowers.mapper.OrderMapper;
import com.system.connect.springboot_flowers.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderItemMapper orderItemMapper;
    
    @Value("${file.export.path:./export}")
    private String exportPath;

    @Override
    @Transactional
    public Order createOrder(OrderCreateDTO orderCreateDTO, Long userId) {
        // 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setOrderNo(generateOrderNo());
        order.setTotalAmount(orderCreateDTO.getTotalAmount());
        order.setPayAmount(orderCreateDTO.getTotalAmount());
        order.setFreightAmount(orderCreateDTO.getFreightAmount());
        order.setPayType(orderCreateDTO.getPaymentType());
        order.setStatus(0); // 待付款
        order.setDeliveryType(orderCreateDTO.getDeliveryType());
        order.setDeliveryTime(orderCreateDTO.getDeliveryTime());
        order.setAddressId(orderCreateDTO.getAddressId());
        order.setNote(orderCreateDTO.getNote());
        order.setInvoiceType(orderCreateDTO.getInvoice() != null ? orderCreateDTO.getInvoice().getType() : null);
        order.setCreatedTime(LocalDateTime.now());
        order.setUpdatedTime(LocalDateTime.now());
        
        // 保存订单
        save(order);
        
        // 保存订单项
        List<OrderItem> orderItems = convertToOrderItems(orderCreateDTO.getItems(), order.getId(), order.getOrderNo());
        saveOrderItems(orderItems);
        
        return order;
    }

    @Override
    public Order getOrderById(Long id) {
        return getById(id);
    }

    @Override
    @Transactional
    public Order updateOrderStatus(Long id, Integer status) {
        Order order = getById(id);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        order.setStatus(status);
        order.setUpdatedTime(LocalDateTime.now());
        updateById(order);
        return order;
    }

    @Override
    public Order getByOrderNo(String orderNo) {
        return this.lambdaQuery()
                .eq(Order::getOrderNo, orderNo)
                .one();
    }

    private String generateOrderNo() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    private List<OrderItem> convertToOrderItems(List<OrderCreateDTO.OrderItemDTO> items, Long orderId, String orderNo) {
        return items.stream()
                .map(item -> {
                    OrderItem orderItem = new OrderItem();
                    orderItem.setOrderId(orderId);
                    orderItem.setOrderNo(orderNo);
                    orderItem.setItemId(item.getItemId());
                    orderItem.setItemName(item.getName());
                    orderItem.setItemImage(item.getImage());
                    orderItem.setItemSpec(item.getSpec());
                    orderItem.setPrice(item.getPrice());
                    orderItem.setQuantity(item.getQuantity());
                    orderItem.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getQuantity())));
                    return orderItem;
                })
                .collect(Collectors.toList());
    }

    @Transactional
    protected void saveOrderItems(List<OrderItem> items) {
        for (OrderItem item : items) {
            orderItemMapper.insert(item);
        }
    }

    @Override
    public List<Order> getOrderList(Long userId, Integer status, Integer page, Integer size) {
        Page<Order> pageParam = new Page<>(page, size);
        
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        if (userId != null) {
            queryWrapper.eq(Order::getUserId, userId);
        }
        
        if (status != null) {
            queryWrapper.eq(Order::getStatus, status);
        }
        
        queryWrapper.orderByDesc(Order::getCreatedTime);
        
        Page<Order> resultPage = this.page(pageParam, queryWrapper);
        return resultPage.getRecords();
    }
    
    @Override
    public int countOrders(LocalDateTime startTime, LocalDateTime endTime) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        
        if (startTime != null) {
            queryWrapper.ge("created_time", startTime);
        }
        
        if (endTime != null) {
            queryWrapper.le("created_time", endTime);
        }
        
        return count(queryWrapper);
    }
    
    @Override
    public int countOrdersByStatus(Integer status, LocalDateTime startTime, LocalDateTime endTime) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        
        queryWrapper.eq("status", status);
        
        if (startTime != null) {
            queryWrapper.ge("created_time", startTime);
        }
        
        if (endTime != null) {
            queryWrapper.le("created_time", endTime);
        }
        
        return count(queryWrapper);
    }
    
    @Override
    public double sumOrderAmount(LocalDateTime startTime, LocalDateTime endTime) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        
        // 只统计已支付的订单
        queryWrapper.eq("status", 1); // 假设1表示已支付状态
        
        if (startTime != null) {
            queryWrapper.ge("created_time", startTime);
        }
        
        if (endTime != null) {
            queryWrapper.le("created_time", endTime);
        }
        
        queryWrapper.select("sum(pay_amount) as total_amount");
        
        Map<String, Object> result = getMap(queryWrapper);
        
        if (result != null && result.get("total_amount") != null) {
            return ((BigDecimal) result.get("total_amount")).doubleValue();
        }
        
        return 0.0;
    }
    
    @Override
    public List<Map<String, Object>> getTopSellingFlowers(int limit, LocalDateTime startTime, LocalDateTime endTime) {
        // 获取订单ID列表
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        
        // 只统计已支付的订单
        orderQueryWrapper.eq("status", 1); // 假设1表示已支付状态
        
        if (startTime != null) {
            orderQueryWrapper.ge("created_time", startTime);
        }
        
        if (endTime != null) {
            orderQueryWrapper.le("created_time", endTime);
        }
        
        List<Order> orders = list(orderQueryWrapper);
        List<Long> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());
        
        if (orderIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 查询订单项销量
        QueryWrapper<OrderItem> itemQueryWrapper = new QueryWrapper<>();
        itemQueryWrapper.in("order_id", orderIds);
        itemQueryWrapper.groupBy("item_id");
        itemQueryWrapper.select("item_id", "item_name", "sum(quantity) as total_quantity", "sum(total_price) as total_amount");
        itemQueryWrapper.orderByDesc("total_quantity");
        itemQueryWrapper.last("limit " + limit);
        
        List<Map<String, Object>> results = orderItemMapper.selectMaps(itemQueryWrapper);
        
        // 格式化结果
        List<Map<String, Object>> formattedResults = new ArrayList<>();
        for (Map<String, Object> row : results) {
            Map<String, Object> formattedRow = new HashMap<>();
            formattedRow.put("itemId", row.get("item_id"));
            formattedRow.put("itemName", row.get("item_name"));
            formattedRow.put("quantity", row.get("total_quantity"));
            formattedRow.put("amount", row.get("total_amount"));
            formattedResults.add(formattedRow);
        }
        
        return formattedResults;
    }
    
    @Override
    public List<Map<String, Object>> getSalesTrend(int days) {
        List<Map<String, Object>> result = new ArrayList<>();
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(days - 1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        
        // 生成日期序列
        for (int i = 0; i < days; i++) {
            LocalDate date = startDate.plusDays(i);
            LocalDateTime dayStart = date.atStartOfDay();
            LocalDateTime dayEnd = date.plusDays(1).atStartOfDay();
            
            // 查询当天订单总金额
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1); // 已支付
            queryWrapper.ge("created_time", dayStart);
            queryWrapper.lt("created_time", dayEnd);
            queryWrapper.select("sum(pay_amount) as total_amount", "count(id) as order_count");
            
            Map<String, Object> dayStats = getMap(queryWrapper);
            
            Map<String, Object> dayResult = new HashMap<>();
            dayResult.put("date", date.format(formatter));
            
            if (dayStats != null && dayStats.get("total_amount") != null) {
                dayResult.put("amount", ((BigDecimal) dayStats.get("total_amount")).doubleValue());
                dayResult.put("count", dayStats.get("order_count"));
            } else {
                dayResult.put("amount", 0.0);
                dayResult.put("count", 0);
            }
            
            result.add(dayResult);
        }
        
        return result;
    }
    
    @Override
    public Map<String, Object> getOrderDetail(Long orderId) {
        // 获取订单基本信息
        Order order = getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 获取订单项
        List<OrderItem> orderItems = getOrderItems(orderId);
        
        // 组装返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("order", order);
        result.put("items", orderItems);
        
        return result;
    }
    
    @Override
    @Transactional
    public Order cancelOrder(Long orderId, String reason) {
        Order order = getById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 检查订单状态，只有待付款的订单才能取消
        if (order.getStatus() != 0) {
            throw new RuntimeException("订单状态不允许取消");
        }
        
        // 更新订单状态为已取消（假设4表示已取消状态）
        order.setStatus(4);
        order.setUpdatedTime(LocalDateTime.now());
        order.setNote(order.getNote() != null ? 
                order.getNote() + " | 取消原因: " + reason : 
                "取消原因: " + reason);
        
        updateById(order);
        
        // 返回更新后的订单
        return order;
    }
    
    @Override
    @Transactional
    public boolean batchUpdateOrderStatus(List<Long> orderIds, Integer status) {
        if (orderIds == null || orderIds.isEmpty()) {
            return false;
        }
        
        UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", orderIds);
        updateWrapper.set("status", status);
        updateWrapper.set("updated_time", LocalDateTime.now());
        
        return update(updateWrapper);
    }
    
    @Override
    public List<OrderItem> getOrderItems(Long orderId) {
        LambdaQueryWrapper<OrderItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderItem::getOrderId, orderId);
        return orderItemMapper.selectList(queryWrapper);
    }
    
    @Override
    public List<Map<String, Object>> getUserRankByAmount(int limit, LocalDateTime startTime, LocalDateTime endTime) {
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        
        // 只统计已支付的订单
        queryWrapper.eq("status", 1); // 假设1表示已支付状态
        
        if (startTime != null) {
            queryWrapper.ge("created_time", startTime);
        }
        
        if (endTime != null) {
            queryWrapper.le("created_time", endTime);
        }
        
        queryWrapper.groupBy("user_id");
        queryWrapper.select("user_id", "sum(pay_amount) as total_amount", "count(id) as order_count");
        queryWrapper.orderByDesc("total_amount");
        queryWrapper.last("limit " + limit);
        
        List<Map<String, Object>> results = baseMapper.selectMaps(queryWrapper);
        
        // 格式化结果
        List<Map<String, Object>> formattedResults = new ArrayList<>();
        for (Map<String, Object> row : results) {
            Map<String, Object> formattedRow = new HashMap<>();
            formattedRow.put("userId", row.get("user_id"));
            formattedRow.put("totalAmount", ((BigDecimal) row.get("total_amount")).doubleValue());
            formattedRow.put("orderCount", row.get("order_count"));
            formattedResults.add(formattedRow);
        }
        
        return formattedResults;
    }
    
    @Override
    public String exportOrders(LocalDateTime startTime, LocalDateTime endTime, Integer status) {
        try {
            // 创建导出目录
            Path exportDir = Paths.get(exportPath);
            if (!Files.exists(exportDir)) {
                Files.createDirectories(exportDir);
            }
            
            // 生成文件名
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            String fileName = "orders_" + timestamp + ".csv";
            Path filePath = exportDir.resolve(fileName);
            
            // 查询订单数据
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            
            if (startTime != null) {
                queryWrapper.ge("created_time", startTime);
            }
            
            if (endTime != null) {
                queryWrapper.le("created_time", endTime);
            }
            
            if (status != null) {
                queryWrapper.eq("status", status);
            }
            
            queryWrapper.orderByDesc("created_time");
            
            List<Order> orders = list(queryWrapper);
            
            // 写入CSV文件
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath.toFile()))) {
                // 写入CSV头
                writer.write("订单ID,订单编号,用户ID,订单金额,支付金额,订单状态,支付方式,创建时间,更新时间\n");
                
                // 写入订单数据
                for (Order order : orders) {
                    writer.write(String.format("%d,%s,%d,%s,%s,%s,%s,%s,%s\n",
                            order.getId(),
                            order.getOrderNo(),
                            order.getUserId(),
                            order.getTotalAmount(),
                            order.getPayAmount(),
                            getOrderStatusText(order.getStatus()),
                            getPayTypeText(order.getPayType()),
                            order.getCreatedTime(),
                            order.getUpdatedTime()
                    ));
                }
            }
            
            return filePath.toString();
        } catch (IOException e) {
            throw new RuntimeException("导出订单数据失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 获取订单状态文本
     */
    private String getOrderStatusText(Integer status) {
        if (status == null) return "未知";
        
        switch (status) {
            case 0: return "待付款";
            case 1: return "已付款";
            case 2: return "已发货";
            case 3: return "已完成";
            case 4: return "已取消";
            default: return "未知状态(" + status + ")";
        }
    }
    
    /**
     * 获取支付方式文本
     */
    private String getPayTypeText(Integer payType) {
        if (payType == null) return "未知";
        
        switch (payType) {
            case 1: return "支付宝";
            case 2: return "微信支付";
            case 3: return "银行卡";
            default: return "未知方式(" + payType + ")";
        }
    }
}
